package com.lsq.tomcat;

import javax.servlet.Servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.io.File;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lsq
 * @description TODO
 * @date 2023/9/14
 */
public class Tomcat {

    private Map<String, Context> contextMap = new HashMap<>();

    public void start() {
        //socket链接 TCP
        try {

            ServerSocket serverSocket = new ServerSocket(8080);
            while (true) {
                Socket accept = serverSocket.accept();
                new SocketProcess(accept, this);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public static void main(String[] args) {
        Tomcat tomcat = new Tomcat();
        tomcat.deployApps();//部署应用
        tomcat.start();
    }

    private void deployApps() {
        File webapps = new File(System.getProperty("user.dir", "webapps"));
        for (String app : webapps.list()) {
            deployApp(webapps, app);
        }
    }

    private void deployApp(File app, String appName) {

        Context context = new Context(appName);
        //找出servlet
        File appDirectory = new File(app, appName);
        File classesDirectory = new File(appDirectory, "classes");
        List<File> filePath = getFilePath(classesDirectory);
        for (File file : filePath) {
            String path = file.getPath();
            path = path.replace(classesDirectory.getPath() + "\\", "");
            path = path.replace(".class", "");
            path = path.replace("\\", ".");
            //加载类
            try {
                WebappClassLoader webappClassLoader = new WebappClassLoader(new URL[]{classesDirectory.toURL()});
                Class<?> aClassServlet = webappClassLoader.loadClass(path);
                if (HttpServlet.class.isAssignableFrom(aClassServlet)) {
                    if (aClassServlet.isAnnotationPresent(WebServlet.class)) {
                        WebServlet annotation = aClassServlet.getAnnotation(WebServlet.class);
                        String[] urlPatterns = annotation.urlPatterns();
                        for (String urlPattern : urlPatterns) {
                            context.addUrlPattern(urlPattern, (Servlet) aClassServlet.newInstance());
                        }
                    }
                }
            } catch (ClassNotFoundException | MalformedURLException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
            contextMap.put(appName, context);
        }

    }

    public Map<String, Context> getContextMap() {
        return contextMap;
    }

    //递归获取文件
    public List<File> getFilePath(File srcFile) {
        List<File> list = new ArrayList<>();
        File[] files = srcFile.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    list.addAll(getFilePath(file));
                } else {
                    list.add(file);
                }
            }
        }
        return list;
    }
}
